<?php

namespace App\Http\Controllers\Admin;

use App\Exports\QhQuestionExport;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Qh_QuestionImportRequest;
use App\Http\Requests\Admin\Qh_QuestionRequest;
use App\Http\Requests\QH\QuestionImportByExcelRequest;
use App\Imports\QhQuestionImport;
use App\Jobs\QuestionDeleteHelperJob;
use App\Models\Qh_Course;
use App\Models\Qh_Knowledge;
use App\Models\Qh_Question;
use App\Models\Qh_QuestionLibrary;
use App\Models\Questions;
use App\Service\Office\PaperImportService;
use App\Service\Office\WordService;
use Carbon\Carbon;
use DB;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Log;
use Maatwebsite\Excel\Facades\Excel;
use PhpOffice\PhpWord\Exception\Exception;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class Qh_QuestionController extends AdminBaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return JsonResponse|object
     */
    public function index()
    {
        $list = Qh_Question::filter(\request()->all())
            ->with(['questionLibrary' => function($q) {
                $q->select(['id', 'name', 'province', 'amount', 'sort']);
            }, 'course' => function($q) {
                $q->select(['id', 'name', 'sort']);
            }, 'knowledge' => function($q) {
                $q->select(['id', 'parentId', 'name', 'sort']);
            }])
            ->orderByDesc('id')
            ->paginate(\request('perPage', 10));
        return $this->restful($list);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param Qh_QuestionRequest $request
     * @return JsonResponse|object
     */
    public function store(Qh_QuestionRequest $request)
    {
        $params = $request->validated();

        $knowledge = Qh_Knowledge::findOrFail($params['knowledgeId']);
        if (empty($params['qlId'])) $params['qlId'] = $knowledge->qlId;
        if (empty($params['courseId'])) $params['courseId'] = $knowledge->courseId;
        if (empty($params['optionCount'])) $params['optionCount'] = count(explode('|NTK|', $params['options']));
        if (empty($params['difficulty'])) $params['difficulty'] = 0;
        if (empty($params['difficultyValue'])) $params['difficultyValue'] = 0;
        if (empty($params['rightCount'])) $params['rightCount'] = 0;
        if (empty($params['wrongCount'])) $params['wrongCount'] = 0;

        $notice = Qh_Question::create($params);

        return $this->restful($notice);
    }

    /**
     * Display the specified resource.
     *
     * @param int $id
     * @return JsonResponse|object
     */
    public function show(int $id)
    {
        return $this->restful();
    }

    /**
     * Update the specified resource in storage.
     *
     * @param Qh_QuestionRequest $request
     * @param int $id
     * @return JsonResponse|object
     */
    public function update(Qh_QuestionRequest $request, int $id)
    {
        $params = $request->validated();
        $knowledge = Qh_Knowledge::findOrFail($params['knowledgeId']);
        if (empty($params['qlId'])) $params['qlId'] = $knowledge->qlId;
        if (empty($params['courseId'])) $params['courseId'] = $knowledge->courseId;
        $params['optionCount'] = count(explode('|NTK|', $params['options']));

        $result = Qh_Question::where('id', $id)->update($params);

        return $this->restful($result);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     * @return JsonResponse|object
     */
    public function destroy(int $id)
    {
        $question = Qh_Question::findOrFail($id);
        try {
            // 从用户的刷题记录、错题集、收藏集中删除该条数据
            QuestionDeleteHelperJob::dispatch($question);
        }catch (\Exception $e) {
            return $this->restful(null, false, '删除失败');
        }
        return $this->restful();
    }

    public function questionDeleteByIds() {
        $ids = explode(',', \request('id'));

        $knowledgeIds = [];
        $questions = Qh_Question::findMany($ids);

        foreach ($questions as $question) {
            $knowledgeIds[] = $question->knowledgeId;
        }

        $result = Qh_Question::whereIn('id', $ids)->delete();

        // 试题数量更新
        foreach ($knowledgeIds as $knowledgeId) {
            updateQhQuestionCount($knowledgeId, 1, 2);
        }
        return $this->restful($result);
    }

    public function getCascadeOptions() {
        $list = Qh_QuestionLibrary::selectRaw('id, name, province')
            ->with(['course' => function($c) {
                $c->selectRaw('id, qlId, name')
                    ->with(['knowledge' => function($k) {
                        $k->selectRaw('id, courseId, id, name')->orderByRaw('sort desc, id asc');
                    }])
                    ->orderByRaw('sort desc, id asc');
            }])
            ->orderByRaw('province asc, sort desc, id asc')
            ->get();

        $list = collect($list)->map(function ($item) {
            return [
                'value' => $item->id,
                'label' => $item->name,
                'province' => $item->province,
                'children' => collect($item->course)->map(function ($course) {
                    return [
                        'value' => $course->id,
                        'label' => $course->name,
                        'children' => \request('not3') ? [] : collect($course->knowledge)->map(function ($knowledge) {
                            return [
                                'value' => $knowledge->id,
                                'label' => $knowledge->name,
                            ];
                        })
                    ];
                })
            ];
        });



        return $this->restful($list);
    }

    /**
     * 导入
     * @param Qh_QuestionImportRequest $request
     * @param WordService $wordService
     * @param PaperImportService $paperImport
     * @return JsonResponse|object
     * @throws Exception
     * @throws \Exception
     */
    public function import(Qh_QuestionImportRequest $request, WordService $wordService, PaperImportService $paperImport) {
        // 表单数据
        $params = $request->validated();

        $course = Qh_Course::findOrFail($params['courseId']);
        if (empty($params['qlId'])) $params['qlId'] = $course->qlId;

        if (empty($params['pathType'])) $params['pathType'] = 1;
        if ($params['pathType'] == 2) {
            $filePath = $params['filePath'];
        } else {
            $filePath = storage_path($params['filePath']);
        }

        if (empty($params['city'])) $params['city'] = null;

        $wordService->imgPath = 'tikuimg/'.$params['courseId'].'/'.Carbon::now()->format('Y/m').'/';
        $paperImport->imgPath = 'tikuimg/'.$params['courseId'].'/'.Carbon::now()->format('Y/m').'/';

        // 所有题目，目前只记录父级题目
        $questionIds = [];
        // 根据题型对题目id分组
        $questionTypeIds = [];

        try {
            // docx 转 html
            $html = $wordService->docx2html($filePath);

            // 解析试卷
            $questions = $wordService->htmlHandle($html, $params['courseId']);
        }catch (Exception $e) {
            Log::error('[试卷导入-格式有误]', (array)$e);
            throw new Exception('试卷格式有误');
        }

        // 入库
        try {
            // 试题入库
            foreach ($questions as $question) {
                $Q = $paperImport->saveQuestionToDatabaseByQiHang($question, $params['courseId'], $params['province'], $params['city'], true);
                if ($Q) {
                    $questionIds[] = $Q['id'];
                    $questionTypeIds[$Q['questionTypeId']][] = $Q['id'];
                }else {
                    throw new Exception('试题入库失败');
                }
            }
        }catch (Exception $e) {
            Log::error('[试卷导入]', (array)$e);
            throw new Exception('导入失败');
        }

        // 成功
        return $this->restful($questionIds);
    }

    /**
     * excel导入
     * @param QuestionImportByExcelRequest $request
     * @return JsonResponse|object
     */
    public function importByExcel(QuestionImportByExcelRequest $request) {
        $params = $request->validated();
        $knowledge = Qh_Knowledge::findOrFail($params['knowledgeId']);
        $course = Qh_Course::findOrFail($knowledge->courseId);
        $params['qlId'] = $course->qlId;
        $params['courseId'] = $course->id;

        $filePath = storage_path($params['filePath']);

        Excel::import(new QhQuestionImport($params), $filePath);

        return $this->restful();
    }

    /**
     * excel导出
     * @throws \Exception
     */
    public function outputByExcel() {
        $ids = request('ids');
        $filename = time().'.xlsx';
        $result = Excel::store(new QhQuestionExport(['ids' => $ids]), $filename, 'public');
        if (!$result) throw new \Exception('导出失败');
        return $this->restful([
            'filename' => $filename,
            'url' => \Storage::disk('public')->url($filename)
        ]);
    }

    /**
     * 导出全部
     * @return JsonResponse|object
     * @throws \Exception
     */
    public function outputAllByExcel() {
        $knowledgeIds = \request('knowledgeIds');

        // 导出全部
        if (empty($knowledgeIds)) {
            $ids = Qh_Question::all()->pluck('id')->toArray();
        }else {
            $knowledgeIds = array_unique(array_filter(explode(',', $knowledgeIds)));
            $ids = Qh_Question::whereIn('knowledgeId', $knowledgeIds)->pluck('id')->toArray();
        }

        $filename = time().'.xlsx';
        $result = Excel::store(new QhQuestionExport(['ids' => $ids]), $filename, 'public');
        if (!$result) throw new \Exception('导出失败');
        return $this->restful([
            'filename' => $filename,
            'url' => \Storage::disk('public')->url($filename)
        ]);
    }

    public function getKnowledgeOptionsByLevel2() {
        $list = [];

        $questionLibrary = Qh_QuestionLibrary::selectRaw('id, id as value, name as label, province')
            ->orderByRaw('province asc, sort desc, id asc')->get();

        foreach ($questionLibrary as $ql) {
            // 查学科
            $courses = Qh_Course::where('qlId', $ql->id)->selectRaw('id, id as value, name as label')->get();
            if (empty($courses)) continue;

            $courseList = [];
            foreach ($courses as $course) {
                // 查一级知识点
                $k1s = Qh_Knowledge::where('courseId', $course->id)->where('level', 1)->selectRaw('id, id as value, name as label, level, parentId')->get();
                if (count($k1s) == 0) continue;

                $k1List = [];
                foreach ($k1s as $k1) {
                    // 查二级知识点
                    $k2s = Qh_Knowledge::where('parentId', $k1->id)->where('level', 2)->selectRaw('id, id as value, name as label, level, parentId')->get();
                    if (count($k2s) == 0) continue;

                    $k1->children = $k2s;
                    $k1List[] = $k1;
                }

                if (empty($k1List)) continue;

                $course->children = $k1List;
                $courseList[] = $course;
            }
            if (empty($courseList)) continue;
            $ql->children = $courseList;
            $list[] = $ql;
        }

        return $this->restful($list);
    }

    public function getQuestionOptions() {
        $level = \request('level');
        $parentId = \request('parentId');
        if (empty($level) && $level != 0) {
            return $this->restful([]);
        }
        $list = [];
        switch ($level) {
            case 0:
                // 题库
                $list = Qh_QuestionLibrary::selectRaw('id, id as value, name as label, province')
                    ->orderByRaw('province asc, sort desc, id asc')->get()->toArray();
                break;
            case 1:
                // 学科
                $list = Qh_Course::where('qlId', $parentId)->selectRaw('id, id as value, name as label')->get()->toArray();
                break;
            case 2:
                // 章
                $list = Qh_Knowledge::where('courseId', $parentId)->where('level', 1)->selectRaw('id, id as value, name as label, level, parentId')->get()->toArray();
                break;
            case 3:
                // 节
                $list = Qh_Knowledge::where('parentId', $parentId)->where('level', 2)->selectRaw('id, id as value, name as label, level, parentId')->get()->toArray();
                break;
        }

        return $this->restful($list);
    }
}
